package design.pattern.Lu19VisitorPattern;

import lombok.Data;

/**
 * @program JavaBase
 * @description: 访问者模式 - 多访问者
 * @author: zhanglu
 * @create: 2020-05-07 23:33:00
 */
public class VisitorPattern05 {

    public static void main(String[] args) {

        CommonEmployee05 commonEmployee05 = new CommonEmployee05();
        commonEmployee05.setName("张三");
        commonEmployee05.setSalary(1000);
        commonEmployee05.setJob("拧螺丝，准备造火箭");


        Manager05 manager05 = new Manager05();
        manager05.setName("里斯");
        manager05.setSalary(10000);
        manager05.setPerformance("拿下xxx客户");

        ShowVisitor showVisitor = new ShowVisitor();
        commonEmployee05.accept(showVisitor);
        showVisitor.report();

        ShowVisitor showVisitor2 = new ShowVisitor();
        manager05.accept(showVisitor2);
        showVisitor2.report();

        TotalVisitor totalVisitor = new TotalVisitor();
        commonEmployee05.accept(totalVisitor);
        System.out.println(totalVisitor.total());

        TotalVisitor totalVisitor2 = new TotalVisitor();
        manager05.accept(totalVisitor2);
        System.out.println(totalVisitor2.total());

    }

}

interface IVisitor05{
    <T> void visit(T t);
}

interface IShow extends IVisitor05{
    void report();
}
interface ITotal extends IVisitor05{
    int total();
}
class ShowVisitor implements IShow{

    private String info;

    @Override
    public void report() {
        System.out.println(this.info);
    }

    @Override
    public <T> void visit(T t) {
        if(t instanceof CommonEmployee05){
            commonEmployee((CommonEmployee05) t);
        }else {
            managerEmployee((Manager05) t);
        }
    }

    private void commonEmployee(CommonEmployee05 commonEmployee05){
        String info = this.getBasicInfo(commonEmployee05);
        info += "\t工作：" + commonEmployee05.getJob();
        this.info = info;
    }

    private void managerEmployee(Manager05 manager05){
        String info = this.getBasicInfo(manager05);
        info += "\t业绩：" + manager05.getPerformance();
        this.info = info;
    }

    private String getBasicInfo(Employee05 employee02){
        String info = "姓名：" + employee02.getName() + "\t薪资：" + employee02.getSalary();
        return info;
    }

}
class TotalVisitor implements ITotal{
    
    private int c1 = 2;
    private int m1 = 5;
    private int cm;
    private int mm;

    @Override
    public <T> void visit(T t) {
        if(t instanceof CommonEmployee05){
            this.cm = this.c1 * ((CommonEmployee05) t).getSalary();
        }else {
            this.mm = this.m1 * ((Manager05) t).getSalary();
        }
    }

    @Override
    public int total() {
        return this.cm + this.mm;
    }
}
@Data
abstract class Employee05{
    private String name;
    private int salary;
    protected abstract void accept(IVisitor05 iVisitor05);
}
@Data
class CommonEmployee05 extends Employee05{

    private String job;

    @Override
    protected void accept(IVisitor05 iVisitor05) {
        iVisitor05.visit(this);
    }
}
@Data
class Manager05 extends Employee05{

    private String performance;

    @Override
    protected void accept(IVisitor05 iVisitor05) {
        iVisitor05.visit(this);
    }
}